#include <stdio.h>

// 指针定义
int main1()
{
    int a = 0;
    //打印a, b的地址
    printf("%p\n", &a);

    //int *代表是一种数据类型，int*指针类型，p才是变量名
    //定义了一个指针类型的变量，可以指向一个int类型变量的地址
    int *p;
    //将a的地址赋值给变量p，p也是一个变量，值是一个内存地址编号
    p = &a;
    //p指向了a的地址，*p就是a的值
    printf("%d\n", *p);
    return 0;
}

// 通过指针间接修改变量的值
int main2()
{
    int a = 10;
    int *p = &a;
    *p = 100;
    char *p3;
    printf("%d\n", a);
    printf("sizeof(p) = %d\n", sizeof(p));
    printf("sizeof(p3) = %d\n", sizeof(p3));

    //&是取地址符号是升维度的（值 -> 指针）
    //*是取值符号是降维度的（指针 -> 值）
    return 0;
}

// 野指针和空指针
int main3()
{
    char ch = 97;
    // int* p = &ch; 值类型必须相同
    /*
    野指针
    任意数值赋值给指针变量没有意义，
    因为这样的指针就成了野指针，此指针指向的区域是未知
    野指针不会直接引发错误，操作野指针指向的内存区域才会出问题。
    */

    //空指针
    /*可以把NULL赋值给此指针，这样就标志此指针为空指针，
    没有任何指针。
    */
    return 0;
}

//万能指针
int main4(void)
{
    int a = 10;
    //万能指针可以接收任意类型变量的内存地址
    void *p = &a;
    //在通过万能指针修改变量的值时  需要找到变量对应的指针类型
    *(int *)p = 100;
    printf("%d\n", a);
    printf("%d\n", *(int *)p);
    printf("万能指针在内存占的字节大小：%d\n", sizeof(void *));
    printf("void在内存占的字节大小：%d\n", sizeof(void));
    return 0;
}

//const修饰的指针
int main()
{
    int a = 100;
    int b = 200;

    //const修饰*p（int）,*p不能改变
    const int *p = &a;
    // *p = 100;//err
    p = &b;
    printf("%d\n", &b);
    printf("%d\n", p);

    //const修饰p1,p1不能改变
    int *const p1 = &a;
    // p1 = &b;//err
    *p1 = 300;
    printf("%d\n", &b);
    printf("%d\n", *p1);

    // 修饰指针变量  只读指针 都不能改变
    const int *const p = &a;
    return 0;
}
